package com.example.java.base.concurrency.flowcontrol.countdownlatch;

import com.example.java.base.concurrency.flowcontrol.MyThreadFactory;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * CountDownLatchDemo1:并发流程控制之-递减计数器(锁存器),用法2 :多等一
 * 应用场景:多个运动员100赛跑,等裁判一声令下
 *
 * @author zhangxiaoxiang
 * @date 2021/4/20
 */
@Slf4j
public class CountDownLatchDemo1 {
    public static void main(String[] args) throws InterruptedException {
        //一个裁判
        CountDownLatch begin = new CountDownLatch(1);
        //创建线程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                5,
                5,
                60L, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(5),
                //自定义线程工厂
                new MyThreadFactory());
        for (int i = 1; i <= 5; i++) {
            final int no = i;
            Runnable runnable = () -> {
                try {
                    Thread.sleep((long) (Math.random() * 1000));
                    log.info("{}号运动员,准备完毕,等待发令枪(这里可以耗时不一样,只是准备过程)", no);
                    //导致当前线程等待，直到锁存器计数为零，除非线程被中断。
                    begin.await();
                    log.info("{}号运动员,开始起步了(这里几乎同一时刻执行的)", no);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            };
            executor.submit(runnable);
        }
        //模拟裁判准备时间
        Thread.sleep(5000);
        log.info("发令枪响起,比赛开始");
        begin.countDown();
        //关闭线程池(根据实际来)
        // executor.shutdown();
    }
}
